package hos.task;

import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.Map;
import java.util.Set;

import hos.core.BuildConfig;
import hos.thread.executor.TS;
import hos.utils.CoreLog;

/**
 * <p>Title: PagingDataAdapter </p>
 * <p>Description:  </p>
 * <p>Company: www.mapuni.com </p>
 *
 * @author : 蔡俊峰
 * @version : 1.0
 * @date : 2023-02-03 10:16
 */
public class PagingRefresh<T> implements Auto.Refresh {
    private final PagingData<T> pagingState = new PagingData<T>();

    private final AutoStatus autoState = AutoStatus.loading();

    private final Auto.AutoPaging<T> autoPaging;
    // 是否运行中，true 运行中
    private boolean isRunning = false;
    // 是否在线程中
    private boolean isThread = true;

    public PagingRefresh(Auto.AutoPaging<T> autoPaging) {
        this.autoPaging = autoPaging;
        pagingState.pageIndex = pagingState.startIndex;
    }

    public void setThread(boolean thread) {
        isThread = thread;
    }

    public boolean isUpdate() {
        return getStartIndex() == getPageIndex();
    }

    public boolean hasMore() {
        return hasMore(null);
    }

    public boolean hasMore(Integer currentSize) {
        if (currentSize == null) {
            return getPageSize() <= pagingState.newSize;
        }
        return getPageSize() <= currentSize;
    }

    public int getStartIndex() {
        return pagingState.startIndex;
    }

    public int getPageSize() {
        return pagingState.pageSize;
    }

    public int getPageIndex() {
        return pagingState.pageIndex;
    }

    public void setStartIndex(int startIndex) {
        pagingState.startIndex = startIndex;
    }

    public void setPageIndex(int pageIndex) {
        pagingState.pageIndex = pageIndex;
    }

    public void setPageSize(int pageSize) {
        pagingState.pageSize = pageSize;
    }

    public void addPage() {
        pagingState.pageIndex++;
    }

    public void resetPage() {
        pagingState.pageIndex = pagingState.startIndex;
    }

    public Map<String, Object> getParamMap() {
        return pagingState.paramMap;
    }

    public List<Object> getParamList() {
        return pagingState.paramList;
    }

    public void setParamMap(Map<String, Object> map) {
        if (map != null) {
            pagingState.paramMap.clear();
            pagingState.paramMap.putAll(map);
        }
    }

    public void setParamList(List<Object> list) {
        if (list != null) {
            pagingState.paramList.clear();
            pagingState.paramList.addAll(list);
        }
    }

    public void setCommonParamList(List<Object> list) {
        if (list != null) {
            pagingState.commonParamList.clear();
            pagingState.commonParamList.addAll(list);
        }
    }

    public void setCommonParamMap(Map<String, Object> map) {
        if (map != null) {
            pagingState.commonParamMap.clear();
            pagingState.commonParamMap.putAll(map);
        }
    }


    public Map<String, Object> getCommonParamMap() {
        return pagingState.commonParamMap;
    }

    public List<Object> getCommonParamList() {
        return pagingState.commonParamList;
    }

    public void changeParams() {
        if (!pagingState.commonParamList.isEmpty()) {
            // 将通用参数添加到使用参数中
            pagingState.paramList.addAll(pagingState.commonParamList);
        }
        if (!pagingState.commonParamMap.isEmpty()) {
            // 将通用参数添加到使用参数中
            pagingState.paramMap.putAll(pagingState.commonParamMap);
        }
    }

    /// 判断是不是空
    boolean isEmpty() {
        return pagingState.isEmpty();
    }

    /// 不是空
    boolean isNotEmpty() {
        return pagingState.isNotEmpty();
    }

    public List<T> getData() {
        return pagingState.data;
    }

    public <F> List<F> convert(Auto.Convert<T, F> function) {
        List<F> list = new ArrayList<>();
        for (T data : getData()) {
            F r = function.convert(data);
            list.add(r);
        }
        return list;
    }

    /// 设置数据
    public PagingRefresh<T> update(Object data) {
        return update(data, new AutoStatus.ChangeStatus() {
            @Override
            public void changed(StatusType statusType) {
                refreshChanged();
            }
        });
    }

    /// 设置数据
    public PagingRefresh<T> update(Object data, AutoStatus.ChangeStatus changeStatus) {
        if (isUpdate()) {
            setData(data);
            if (isEmpty()) {
                autoState.changeEmpty(changeStatus);
            } else {
                autoState.changeSuccess(changeStatus);
            }
            return this;
        }
        add(data);
        if (isEmpty()) {
            autoState.changeEmpty(changeStatus);
        } else {
            autoState.changeSuccess(changeStatus);
        }
        return this;
    }

    /// 设置数据
    public void setData(Object data) {
        pagingState.data.clear();
        add(data);
    }

    /// 添加数据
    @SuppressWarnings("unchecked")
    public void add(Object data) {
        if (data == null) {
            return;
        }
        if (data instanceof Collection) {
            pagingState.newSize = ((Collection<?>) data).size();
            pagingState.data.addAll((Collection<? extends T>) data);
        } else if (data instanceof Map) {
            pagingState.newSize = 1;
            pagingState.data.add((T) data);
        } else {
            pagingState.newSize = 1;
            pagingState.data.add((T) data);
        }
    }

    /// 获取列表的数量
    public int getItemCount() {
        return pagingState.count();
    }

    /// 获取列表的Item
    public T getItem() {
        return getItem(0);
    }

    /// 获取列表的Item
    public T getItem(int index) {
        return isEmpty() ? null : pagingState.data.get(index);
    }

    /// 获取列表的Item
    @SuppressWarnings("unchecked")
    public <F> F getMap(String key, int index) {
        if (isEmpty()) {
            return null;
        }
        Map<String, F> map = (Map<String, F>) getItem(index);
        return map.get(key);
    }

    /**
     * 释放
     */
    public void dispose() {
        pagingState.clear();
    }

    /**
     * 状态变化
     */
    public AutoStatus status() {
        return autoState;
    }

    /// 更换界面状态
    public void changeLoadState(StatusType value, AutoStatus.ChangeStatus changeStatus) {
        autoState.changeLoadStatus(value, changeStatus);
    }

    /**
     * 当前状态
     */
    public StatusType statusType() {
        return autoState.statusType();
    }

    /// 刷新页面
    @Override
    public void refresh() {
        if (isThread) {
            TS.postIo(new Runnable() {
                @Override
                public void run() {
                    refreshRun();
                }
            });
            return;
        }
        refreshRun();
    }

    /**
     * 刷新页面
     */
    protected void refreshRun() {
        if (isRunning) {
            // 运行中，不在重复运行
            CoreLog.d("refresh running");
            return;
        }
        try {
            // 打印参数
            printParam();
            CoreLog.d("refresh start");
            isRunning = true;
            autoState.changeLoading(new AutoStatus.ChangeStatus() {
                @Override
                public void changed(StatusType statusType) {
                    refreshChanged();
                }
            });
            CoreLog.d("refresh running");
            /// 同步，按照正确的返回  异步，直接返回Loading或者null
            Object obj = autoPaging.run(this);
            if (isThread && obj != null) {
                // 更新数据
                update(obj, new AutoStatus.ChangeStatus() {
                    @Override
                    public void changed(StatusType statusType) {
                        refreshChanged();
                    }
                });
            }
            CoreLog.d("refresh success");
        } catch (Exception e) {
            CoreLog.e("refresh error", e);
            autoState.changeFailed(new AutoStatus.ChangeStatus() {
                @Override
                public void changed(StatusType statusType) {
                    refreshChanged();
                }
            });
        } finally {
            isRunning = false;
            CoreLog.d("refresh end");

        }
    }

    /**
     * 打印参数
     */
    private void printParam() {
        if (BuildConfig.DEBUG) {
            for (Object obj : getCommonParamList()) {
                CoreLog.d("commonParamList：" + obj.toString());
            }
            Set<String> commonMapKeys = getCommonParamMap().keySet();
            for (String key : commonMapKeys) {
                CoreLog.d("commonParamMap：" + key + "=" + getCommonParamMap().get(key));
            }
            for (Object obj : getParamList()) {
                CoreLog.d("paramList：" + obj.toString());
            }
            Set<String> mapKeys = getParamMap().keySet();
            for (String key : mapKeys) {
                CoreLog.d("paramMap：" + key + "=" + getParamMap().get(key));
            }
        }
    }

    /**
     * 加载中发生变化
     */
    private void refreshChanged() {
        autoPaging.changed(this);
    }
}
